package com.tczs.client;

import com.alibaba.fastjson.JSONObject;
import com.tczs.client.bean.Command;
import com.tczs.client.bean.Where;
import com.tczs.client.service.ClientService;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil;
import org.apache.log4j.Logger;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *客户端
 */
public class Client {

    private static Logger logger = Logger.getLogger(Client.class);
    public  static final Map<Long, Client> LONG_CLIENT_MAP = new HashMap<>();
    public  static final Map<ChannelId, Long> CHANNEL_ID_LONG_MAP = new HashMap<>();
    public  ChannelId channelId;
    public  AtomicInteger requestId = new AtomicInteger(0);
    private ChannelFuture future = null;
    private EventLoopGroup group = null;

    public void start(String ip,int port,Long id){
        group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ClientChannelInitializer());
        future = bootstrap.connect(
                new InetSocketAddress(ip,port)
        );
//        System.out.println(future.channel().id()+"  000");
//        System.out.println(future.channel().id()+"  000");
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                if (channelFuture.isSuccess()) {
                    logger.info("Connection success");
                    channelId = future.channel().id();
                    CHANNEL_ID_LONG_MAP.put(channelId,id);
                } else {
                    logger.error("Connection failed");
                    channelFuture.cause().printStackTrace();
                }
            }
        });
    }

    public void close(){
        try{
            future.channel().closeFuture().sync();
            Long removeId = CHANNEL_ID_LONG_MAP.remove(channelId);
            LONG_CLIENT_MAP.remove(removeId);
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            try {
                group.shutdownGracefully().sync();
            } catch (InterruptedException e) {
                logger.error(e);
            }
        }
    }

    /**
     * 客户端直接发送请求数据到服务端
     * @param message
     */
    public void send(String message){
        ChannelFuture future = this.future.channel().writeAndFlush(Unpooled.copiedBuffer(message, CharsetUtil.UTF_8));
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                if (channelFuture.isSuccess()) {
                    logger.info("发送成功");
                } else {
                    logger.error("发送失败");
                    channelFuture.cause().printStackTrace();
                }
            }
        });
        logger.info("客户端向服务端发送请求数据:"+ message);
    }

    public static void main(String[] args) throws InterruptedException {
//        Client client = new Client();
//        client.start("localhost",8080,-1L);
        Command command = new Command();
        command.setCommandName("select");
        command.setDatabaseName("test2");
        command.setTableName("Order");
        Where where = new Where();
        where.LIMIT(2L);
        command.setWhere(where);
//        String commandStr = JSONObject.toJSONString(command);
        int i =0;
        while(i<10) {
            ClientService.send(null,command);
            i++;
        }

    }
}
